<?php

namespace app\mini\controller\dealer;

use app\common\enum\order\OrderStatus;
use app\common\enum\order\OrderType;
use app\common\enum\account\PayeeType;
use app\common\enum\order\ReasonType;
use app\common\enum\order\ReceiveType;
use app\common\enum\purchase\OrderStatus as PurchaseStatus;
use app\common\enum\purchase\OrderType as PurchaseOrderType;
use app\common\model\AccountRecord;
use app\common\model\DealerCharge;
use app\common\model\ReceiveLog;
use app\common\model\SalesmanDealer;
use app\common\service\annotation\ControllerAnnotation;
use app\common\service\annotation\NodeAnnotation;
use app\common\controller\ApiController;
use app\company\model\AccountPaymentOrder;
use app\company\model\CompanyOrder;
use app\company\model\CompanyTransferOrder;
use app\company\model\DealerOrder;
use think\App;
use think\response\Json;

/**
 * @ControllerAnnotation (title="经销商看板")
 */
class Board extends ApiController
{
    /**
     * @var array|mixed
     */
    private mixed $board_type;
    private CompanyOrder $orderModel;

    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->board_type = $this->request->get('type') ?? 1;
        $this->orderModel = new CompanyOrder();
    }

    /**
     * @NodeAnnotation (title="看板入口")
     * @return Json
     */
    public function entrance(): Json
    {
        return match ($this->board_type) {
            '1' => $this->manage(),
            '2' => $this->dealer(),
            '3' => true,
            default => $this->error('类型参数错误'),
        };
    }

    /**
     * @NodeAnnotation (title="经营分析")
     * @return Json
     */
    private function manage(): Json
    {
        $res = $this->dealTime();
        $startTime = $res['startTime'];
        $endTime = $res['endTime'];
        $where = [
            ['pid','<>',0],
            ['dealer_id','=',$this->uid],
            ['order_status','=',OrderStatus::FINISH],
            ['order_type', '=', OrderType::SALES],
            ['create_time', '>=', $startTime],
            ['create_time', '<', $endTime],
        ];
        $total_amount = $this->orderModel->where($where)->sum('order_amount');
        $now_amount = $this->orderModel->where($where)->where('receive_type',ReceiveType::NOW)->sum('pay_amount');
        $yc_amount = $this->orderModel->where($where)->where('receive_type',ReceiveType::YC)->sum('order_amount');
        $zq_amount = $this->orderModel->where($where)->where('receive_type',ReceiveType::ZQ)->sum('order_amount');
        $owe_amount = $this->orderModel->where($where)->where('receive_type',ReceiveType::NOW)->sum('unsay_amount');
        // 获取业务员
        $salesmanIds = (new SalesmanDealer())->where('dealer_id',$this->uid)->column('salesman_id');
        // 查询充值
        $cz = (new ReceiveLog())->where('payee_type',PayeeType::SALESMAN)->where('reason',ReasonType::YC)
            ->where('payee_id', 'in',$salesmanIds)->sum('money');
        $data = [
            'total_amount' => $total_amount,
            'now_amount' => $now_amount,
            'yc_amount' => $yc_amount,
            'zq_amount' => $zq_amount,
            'owe_amount' => $owe_amount,
            'cz_amount' => $cz,
            'ys_amount' => $cz + $now_amount,
            'qk_amount' => $zq_amount + $owe_amount,
        ];
        return $this->success($data, '查询成功');
    }

    /**
     * @NodeAnnotation (title="经销商分析")
     * @return Json
     */
    private function dealer(): Json
    {
        $get = $this->request->get();
        if(empty($get['date'])) return $this->error('日期参数错误！');
        $data = [];
        return $this->success($data);
    }

    public function report(): Json
    {
        $res = $this->dealTime();
        $startTime = $res['startTime'];
        $endTime = $res['endTime'];
        $where = [
            ['pid','<>',0],
            ['dealer_id','=',$this->uid],
//            ['order_status','=',OrderStatus::FINISH],
            ['check_status','=',2],
            ['create_time', '>=', $startTime],
            ['create_time', '<', $endTime],
        ];
        $saleWhere = $where;
        $saleWhere[] = ['order_type', '=', OrderType::SALES];
        $receiveModel = new ReceiveLog();
        $salesmanDealerModel = new SalesmanDealer();
//        $dealerCharge = new DealerCharge();
        // 查询业务员ID数组
        $salesmanIds = $salesmanDealerModel->where('dealer_id',$this->uid)->column('salesman_id');
        $paymentWhere = [
            ['payee_type', '=',PayeeType::SALESMAN],
            ['payee_id', 'in',$salesmanIds],
        ];
        $tc_rate_total_money = $tp_rate_total_money = $tx_rate_total_money = 0;
        $xsOutData = (new CompanyOrder())->with([
            'detail' => function ($query) {
                $query->with([
                    'goods' => function ($query) {
                        $query->field('id,image,name')->withTrashed();
                    },
                    'goodsSpec' => function ($query) {
                        $query->field('id,image,name,unit,sale_price')->withTrashed();
                    }
                ]);
            },
            'store' => function ($query) {
                $query->field('id,name,contact,phone,address');
            },
            'dealer' => function ($query) {
                $query->field('id,name,tc_rate,tp_rate,tx_rate');
            },
            'salesman' => function ($query) {
                $query->field('id,rename');
            }
        ])
            ->where('order_type', OrderType::SALES)
            ->where('dealer_id', $this->uid)
            ->where('create_time','between',[$startTime,$endTime])
            ->where('pid', '<>', 0)
            ->where('order_status', '<>', OrderStatus::CANCEL)
            ->where('check_status', '=', 2)
            ->where('is_cx',1)->select();
        foreach($xsOutData as &$item){
            $detail = $item->detail->toArray();
            $outMoney_all = $financeMoney_all = 0;
            array_walk($detail, function ($v) use (&$outMoney_all,&$financeMoney_all,$item,&$tc_rate_total_money,&$tp_rate_total_money,&$tx_rate_total_money) {
                $outMoney_all = $v['goods_type'] == 1 && $v['true_price'] > 0 ? $v['total_price']  : bcadd($outMoney_all, bcmul($v['num'], $v['goodsSpec']['sale_price'], 2), 2);
                $money = $v['sale_price'];
                if ($v['goods_type'] == 1) $money = $v['true_price'];
                $financeMoney_all = bcadd($financeMoney_all, bcmul($v['num'], $money, 2), 2);
            });
            $tc_rate_money = floatval($outMoney_all) * floatval($item['dealer']['tc_rate'])/100;
            $tp_rate_money = $item['is_self_order']== 1 ? floatval($outMoney_all) * floatval($item['dealer']['tp_rate'])/100 : 0;
            $tx_rate_money = $item['is_self_order']== 1 ? floatval($outMoney_all) * floatval($item['dealer']['tx_rate'])/100 : 0;
            $item->finance_money = sprintf("%.2f",($tc_rate_money +  $tp_rate_money +  $tx_rate_money)) ;
            $item->out_money = $outMoney_all;
        };
        $ctWhere[] = ['order_type', '=', PurchaseOrderType::CT];
        $ctWhere[] = ['order_status', 'in', [PurchaseStatus::PASS, PurchaseStatus::PUT_IN, PurchaseStatus::FINISHED]];
        $ctOutMoney = (new DealerOrder())->where($ctWhere)->where('dealer_id', $this->uid)->where('create_time','between',[$startTime,$endTime])->sum('order_amount');
        $dbOutData = (new CompanyTransferOrder())->where('dealer_id', $this->uid)
            ->where('check_status', '<>', 1)->where('create_time','between',[$startTime,$endTime])
            ->whereIn('transfer_type', [1, 3])->select()->each(function ($item)
            {
                $tc_rate_total_money = $tc_rate_total_money = $tc_rate_total_money = 0;
                $item->detail = $item->detail->each(function ($vo) use ($item,&$tc_rate_total_money, &$tp_rate_total_money, &$tx_rate_total_money)
                {
                    $vo->goods  = $vo->goods()->withTrashed()->find();
                    $vo->spec   = $vo->spec()->withTrashed()->find();
                    $vo->amount = $total_price = bcmul($vo->transfer_num, $vo->spec->sale_price);

                    $tc_rate_money       = $item->dealer->tc_rate == 0 ? 0 : bcmul($total_price, $item->dealer->tc_rate / 100,2);
                    $tp_rate_money = 0;
                    $tx_rate_money = 0;
                    if(in_array($item->transfer_type,[1,3]) && $item->transfer_mode == 1) $tp_rate_money = $item->dealer->tp_rate == 0 ? 0 : bcmul($total_price, $item->dealer->tp_rate / 100,2);
                    $tc_rate_total_money += $tc_rate_money;
                    $tp_rate_total_money += $tp_rate_money;
                    $tx_rate_total_money += $tx_rate_money;
                });
                $item->rate_total_money = $tc_rate_total_money + $tp_rate_total_money + $tx_rate_total_money;
                $item->amount = round(array_sum(array_column($item->detail->toArray(), 'amount')), 2);
                return $item;
            });
        $data = [
            'order' => [
                'order_money' => $this->orderModel->where($saleWhere)->sum('order_amount'),
                'order_sk' => $this->orderModel->where($saleWhere)->sum('pay_amount'),
                'order_tk' => $this->orderModel->where($where)->where('order_type',OrderType::RETURN)->sum('order_amount'),
                'yfs' => $receiveModel->where($paymentWhere)->where('reason',ReasonType::YC)->sum('money'),
                'yfz' => $this->orderModel->where($saleWhere)->where('receive_type',ReceiveType::YC)->sum('order_amount'),
                'zqs' => $this->orderModel->where($saleWhere)->where('receive_type',ReceiveType::ZQ)->sum('pay_amount'),
                'zqd' => $this->orderModel->where($saleWhere)->where('receive_type',ReceiveType::ZQ)->sum('unsay_amount'),
                'gz' => $this->orderModel->where($saleWhere)->where('receive_type',ReceiveType::NOW)->sum('unsay_amount'),
                'gzje' => $this->orderModel->where($saleWhere)->where('receive_type',ReceiveType::NOW)->where('pay_amount',0)->sum('unsay_amount'),
                'ss' => $this->orderModel->where($saleWhere)->sum('pay_amount'),
//                'out_money' => $dealerCharge->where('dealer_id',$this->uid)->where('create_time','between',[$startTime,$endTime])->sum('out_money'),
//                'service_money' => $dealerCharge->where('dealer_id',$this->uid)->where('create_time','between',[$startTime,$endTime])->sum('money'),
                'out_money' => round(array_sum(array_column($xsOutData->toArray(), 'out_money')) + $ctOutMoney + array_sum(array_column($dbOutData->toArray(), 'amount')), 2),
                'service_money' => round(array_sum(array_column($xsOutData->toArray(), 'finance_money')) + array_sum(array_column($dbOutData->toArray(), 'rate_total_money')), 2),
            ],
            'xs' => [
                'order_count' => $this->orderModel->where($saleWhere)->count(),
                'order_sk' => $this->orderModel->where($saleWhere)->sum('pay_amount'),
                'gz' => $this->orderModel->where($saleWhere)->where('receive_type',ReceiveType::NOW)->sum('unsay_amount'),
                'zqd' => $this->orderModel->where($saleWhere)->where('receive_type',ReceiveType::ZQ)->sum('unsay_amount'),
            ],
            'tk' => [
                'order_count' => $this->orderModel->where($where)->where('order_type',OrderType::RETURN)->count(),
                'order_money' => $this->orderModel->where($where)->where('order_type',OrderType::RETURN)->sum('order_amount'),
            ],
            'yf' => [
                'count' => $receiveModel->where($paymentWhere)->where('reason',ReasonType::YC)->count(),
                'yfs' => $receiveModel->where($paymentWhere)->where('reason',ReasonType::YC)->sum('money'),
                'yfz' => $this->orderModel->where($saleWhere)->where('receive_type',ReceiveType::YC)->sum('order_amount'),
                'balance' => 0,
            ],
        ];
        return $this->success($data, '查询成功');
    }

    private function dealTime()
    {
        $get = $this->request->get();
        if(empty($get['date'])) return $this->error('日期参数错误！');
        // 查询已完成的对应经销商的订单
        // 处理时间
        $count = substr_count($get['date'],'-');
        switch ($count) {
            case 0:
                $startTime = strtotime(date($get['date'].'-1-1 00:00:00'));
                $endTime = strtotime(date(($get['date'] + 1).'-1-1 00:00:00'));
                break;
            case 1:
                $startTime = strtotime($get['date']);
                $endTime = strtotime($get['date'].'-1' . ' +1 month');
                break;
            case 2:
                $startTime = strtotime($get['date']);
                $endTime = $startTime + 86400;
                break;
            default:
                $startTime = strtotime(date('Y-m-d' ,time()).'00:00:00');
                $endTime = $startTime + 86400;
        }
        return ['startTime'=>$startTime,'endTime'=>$endTime];
    }

    public function account(): Json
    {
        $get = $this->request->get();
        $model = new AccountPaymentOrder();
        $accountRecord = new AccountRecord();
        $where = [
            ['payee_type','=',PayeeType::DEALER],
            ['payee_id','=',$this->uid],
        ];
        $list = $model->where($where)->paginate($get['limit']??15) ?? [];

        $total_money = $model->where($where)->sum('amount') ?? 0;
        $no_settled = $accountRecord->where($where)->value('fz_money') ?? 0;
        $settled = bcsub($total_money, $no_settled,2) ?? 0;

        $data = [
            'money' => [
                'total_money' => $total_money,
                'no_settled' => $no_settled,
                'settled' => $settled,
            ],
            'list' => $list
        ];
        return $this->success($data, '查询成功');
    }

    public function accountDetail(): Json
    {
        $receiveLog = new ReceiveLog();
        $orderModel = new CompanyOrder();
        // 查询订单
        $orderIds = $orderModel->where('dealer_id','=',$this->uid)->where('order_type',1)->column('id');
        $list = $receiveLog->field('YEAR(FROM_UNIXTIME(create_time)) as year,MONTH(FROM_UNIXTIME(create_time)) as month,DAY(FROM_UNIXTIME(create_time)) as day,sum(money) as order_money')
            ->group('YEAR(FROM_UNIXTIME(create_time)),MONTH(FROM_UNIXTIME(create_time)),DAY(FROM_UNIXTIME(create_time))')->where('company_order_id','in',$orderIds)->order('id desc')
            ->paginate($this->request->get('limit')??15)->each(function ($item){
                $date = $item['year'].'-'.$item['month'].'-'.$item['day'];
                $startTime = strtotime(date($date.' 00:00:00'));
                $endTime = strtotime(date($date.' 23:59:59'));
                $item->fee = (new DealerCharge())->where('create_time','between',[$startTime,$endTime])->sum('money');
                $item->money = bcsub($item->order_money,$item->fee,2);
            });

        return $this->success($list);
    }

}